<template>
  <el-popover
    placement="bottom-end"
    width="500px"
    popper-class="advanced-search-pop"
    :visible="visible"
    @show="popverShow"
  >
    <template #reference>
      <el-button @click="popverShow" class="advanced-search-btn" :type="searchType ? 'primary' : ''">
        <i class="MC_iconfont MC_icon-shaixuan2-xian"></i>
        {{ cusBtnName }}
      </el-button>
    </template>
    <div class="custom-title">
      <span>更多筛选</span>
      <i class="MC_iconfont MC_icon-tianjia-xian" @click="showCustomSearch" />
    </div>
    <div class="common-con-title"><i class="MC_iconfont MC_icon-shaixuan2-xian"></i>常用筛选</div>
    <div class="custom-common">
      <div class="common-list" v-for="(item, index) in customList" :key="index" @click="customClick(item)">
        <span>{{ item.name }}</span>
        <span class="common-list-operate">
          <i class="MC_iconfont MC_icon-bianji1-xian" v-show="!item.default" @click.stop="editCustomClick(item)" />
          <i v-show="!item.default" class="MC_iconfont MC_icon-shanchu1-xian" @click.stop="deleteCustomClick(item)" />
        </span>
      </div>
    </div>
    <div v-show="isShowCustom" class="custom-box">
      <div class="custom-con-title"><i class="MC_iconfont MC_icon-shaixuan"></i>自定义筛选</div>
      <el-input v-model.trim="customName" placeholder="请输入">
        <template #prepend>
          <span>名称</span>
        </template>
      </el-input>
      <div class="common-title">筛选条件</div>
      <div class="common-condition-con">
        <div v-for="(con, idx) in allConditions" :key="idx">
          <div class="common-contition-list" :key="cItem.key" v-for="(cItem, index) in con">
            <span class="order-num">{{ index + 1 }}.</span>
            <el-select
              v-model="cItem.fieldKey"
              placeholder="请选择"
              @change="fieldChange(cItem, index)"
              filterable
              style="flex: 0 0 112px"
            >
              <el-option v-for="item in fieldList" :key="item.value" :label="item.label" :value="item.prop">
              </el-option>
            </el-select>
            <el-select
              v-model="cItem.fieldOperator"
              placeholder="请选择"
              style="flex: 0 0 87px"
              @change="fieldSelect(cItem)"
            >
              <el-option
                v-for="item in conditionList[cItem.fieldKey] ? conditionList[cItem.fieldKey].condition : []"
                :key="item"
                :label="getConditionText(item)"
                :value="item"
              >
              </el-option>
            </el-select>
            <type-component
              ref="typeComponent"
              :props="
                conditionList[cItem.fieldKey] && conditionList[cItem.fieldKey].props
                  ? conditionList[cItem.fieldKey].props
                  : { label: 'name', value: '_id' }
              "
              :type="conditionList[cItem.fieldKey] ? conditionList[cItem.fieldKey].type : ''"
              :condition="cItem.fieldOperator"
              :selectList="fieldSelectList[cItem.fieldKey]"
              v-model="cItem.fieldValue"
              v-bind:key="cItem.key"
            ></type-component>
            <span @click.stop="deleteCondition(con, index)"
              ><i class="MC_iconfont MC_icon-shanchu2-xian delet-span"></i
            ></span>
          </div>
          <div @click="conditionAdd(idx)" class="add-btn"><i class="MC_iconfont MC_icon-tianjia-xian"></i>添加条件</div>
          <el-divider content-position="center">或</el-divider>
        </div>
        <div @click="allConditionAdd" class="add-btn"><i class="MC_iconfont MC_icon-tianjia-xian"></i>添加条件</div>
      </div>
    </div>
    <div v-show="isShowCustom" class="oprate">
      <el-button @click="saveCondition">保存为常用检索</el-button>
      <el-button type="primary" @click="searchClick">检索</el-button>
    </div>
  </el-popover>
</template>

<script lang="ts">
import { defineComponent, reactive, computed, onMounted, toRefs, nextTick, getCurrentInstance, watch } from 'vue'
import { v4 as uuidv4 } from 'uuid'
import cloneDeep from 'lodash/cloneDeep'
import { ElMessage } from 'element-plus'
import typeComponent from './component-type.vue'
export default defineComponent({
  name: 'AdvancedSearch',
  components: { typeComponent },
  props: {
    customList: {
      type: Array,
      default: () => []
    },
    fieldSelectList: {
      type: Object,
      default: () => ({})
    },
    fieldList: {
      type: Array,
      default: () => []
    },
    conditionList: {
      type: Object,
      default: () => ({})
    },
    searchType: {
      // 是否为高级检索
      type: Boolean,
      default: false
    }
  },
  emits: ['onSearchFun', 'onSaveCondition', 'onDeleteCustomClick'],
  setup(props, { emit }) {
    const state = reactive({
      isDoc: false,
      visible: false,
      isShowCustom: false,
      customName: '',
      currentCustomId: '',
      allConditions: [
        [
          {
            fieldKey: '',
            fieldOperator: '',
            fieldValue: [],
            key: uuidv4()
          }
        ]
      ]
    })

    const instance: any = getCurrentInstance()

    const getConditionText = (type: string) => {
      /**
       * 'eq'-等于  'neq'-不等于  'in'-包含  'nin'-不包含  'empty'-为空  'nempty'-不为空
       * 'gt'-大于  'gte'-大于等于  'lt'-小于  'lte'-小于等于  'between'-介于  'nbtn'-不介于
       *  */
      let label
      switch (type) {
        case 'eq':
          label = '等于'
          break
        case 'neq':
          label = '不等于'
          break
        case 'in':
          label = '包含'
          break
        case 'nin':
          label = '不包含'
          break
        case 'empty':
          label = '为空'
          break
        case 'nempty':
          label = '不为空'
          break
        case 'gt':
          label = '大于'
          break
        case 'gte':
          label = '大于等于'
          break
        case 'lt':
          label = '小于'
          break
        case 'lte':
          label = '小于等于'
          break
        case 'between':
          label = '介于'
          break
        case 'nbtn':
          label = '不介于'
          break
      }
      return label
    }

    const cusBtnName = computed(() => {
      if (props.searchType && state.customName) {
        return state.customName
      } else {
        return '高级筛选'
      }
    })

    onMounted(() => {
      document.onclick = () => {
        state.isDoc = true
      }
    })

    const fieldChange = (item: any) => {
      item.fieldValue = []
      const fieldKey = item.fieldKey
      const fieldOperator = (props.conditionList[fieldKey] as any).condition[0]
      item.fieldOperator = fieldOperator
    }

    const conditionAdd = (idx: number) => {
      state.allConditions[idx].push({
        fieldKey: '',
        fieldOperator: '',
        fieldValue: [],
        key: uuidv4()
      })
    }

    const allConditionAdd = () => {
      state.allConditions.push([
        {
          fieldKey: '',
          fieldOperator: '',
          fieldValue: [],
          key: uuidv4()
        }
      ])
    }

    const deleteCondition = (item: any, index: number) => {
      item.splice(index, 1)
      if (item && !item.length) {
        state.allConditions = state.allConditions.filter((v: any) => v.length)
      }
    }

    const searchClick = () => {
      if (checkValue()) {
        emit('onSearchFun', { advanceQuery: checkValue() })
      }
    }

    const saveCondition = () => {
      if (!state.customName) {
        ElMessage({ message: '请输入高级筛选名称！', type: 'error' })
        return false
      }
      if (checkValue()) {
        emit('onSaveCondition', {
          name: state.customName,
          advanceQuery: checkValue(),
          currentCustomId: state.currentCustomId
        })
        state.isShowCustom = false
        state.currentCustomId = ''
      }
    }

    const popverShow = () => {
      state.visible = true
      document.addEventListener('click', clickFun)
    }

    const clickFun = async (e: any) => {
      await nextTick()
      let isFocus = false
      instance?.refs.typeComponent.some((item: any) => {
        if (item.isFocus) {
          isFocus = true
          return true
        }
      })
      const pop = document.getElementsByClassName('advanced-search-pop')[0]
      const btn = document.getElementsByClassName('advanced-search-btn')[0]
      if (!(pop && pop.contains(e.target)) && !(btn && btn.contains(e.target)) && !isFocus) {
        state.visible = false
      }
    }

    const showPopover = () => {
      state.visible = true
    }

    const hidePopover = () => {
      state.visible = false
    }

    const showCustomSearch = () => {
      state.customName = ''
      state.currentCustomId = ''
      state.allConditions = [
        [
          {
            fieldKey: '',
            fieldOperator: '',
            fieldValue: [],
            key: uuidv4()
          }
        ]
      ]
      state.isShowCustom = true
    }

    const customClick = (item: any) => {
      state.customName = item.name
      state.currentCustomId = item._id
      state.isShowCustom = false
      emit('onSearchFun', { advanceQuery: item.conditions, id: item._id })
    }

    const editCustomClick = (item: any) => {
      state.currentCustomId = item._id
      state.customName = item.name
      state.allConditions = cloneDeep(item.conditions)
      state.isShowCustom = true
    }

    const deleteCustomClick = (item: any) => {
      emit('onDeleteCustomClick', item)
      if (state.currentCustomId === item._id) {
        state.isShowCustom = false
        state.currentCustomId = ''
        state.customName = ''
      }
    }

    const checkValue = () => {
      let check = false
      const checkList = cloneDeep(state.allConditions)
      checkList.forEach((v) => {
        v.some((item: any) => {
          if (item.key) {
            delete item.key
          }
          if (item.fieldOperator === 'between') {
            if (!item.fieldValue[1] || item.fieldValue[1].length === 0) {
              check = true
              return true
            }
          }
          // 为空 不为空 不需要值
          if (item.fieldOperator !== 'empty' && item.fieldOperator !== 'nempty') {
            if (!item.fieldValue[0] || item.fieldValue[0].length === 0) {
              check = true
              return true
            }
          }
        })
      })
      if (check || checkList.length === 0) {
        ElMessage({ message: '存在空值条件，请检查！', type: 'error' })
        return false
      }
      return checkList
    }

    const fieldSelect = (item: any) => {
      item.fieldValue = []
    }

    return {
      ...toRefs(state),
      getConditionText,
      cusBtnName,
      fieldChange,
      conditionAdd,
      allConditionAdd,
      deleteCondition,
      searchClick,
      saveCondition,
      popverShow,
      showPopover,
      showCustomSearch,
      customClick,
      editCustomClick,
      deleteCustomClick,
      fieldSelect,
      hidePopover
    }
  }
})
</script>

<style lang="stylus" scoped>
.MC_icon-shaixuan2-xian
  margin-right 6px
.custom-title
  font-size 16px
  font-weight 500
  display flex
  justify-content space-between
  align-items center
  box-shadow inset 0px -1px 0px rgba(0, 0, 0, 0.05)
  padding 16px
  color rgba(0, 0, 0, 0.88)
  .MC_icon-tianjia-xian
    color var(--mc-link-color)
    font-size 18px
.common-con-title
  padding 16px 16px 12px
  font-weight 500
  font-size 14px
  color rgba(0, 0, 0, 0.88)
  .MC_icon-shaixuan2-xian
    color rgba(0, 0, 0, 0.6)
.custom-common
  max-height 70px
  overflow-y scroll
  padding-bottom 4px
  .common-list
    height 36px
    padding 0 8px
    display flex
    flex-direction row
    justify-content space-between
    align-items center
    cursor pointer
    border-radius 4px
    margin 0 16px
    .common-list-operate
      display none
      .MC_iconfont
        color #a5a5ad
        cursor pointer
        margin-right 10px
        font-size 16px
        &:last-child
          margin-right 0
    &:hover
      background var(--mc-gray2-color)
      .common-list-operate
        display block
.custom-box
  border-top 1px solid rgba(0, 0, 0, 0.05)
  padding 16px
  .custom-con-title
    font-weight 500
    font-size 14px
    color rgba(0, 0, 0, 0.88)
    margin-bottom 16px
    .MC_iconfont
      color rgba(0, 0, 0, 0.6)
      margin-right 6px
  :deep(.el-input-group__prepend)
    background #fff
    padding 0px 8px
    border-right none
    color rgba(0, 0, 0, 0.6)
  .common-title
    font-weight 500
    font-size 14px
    color rgba(0, 0, 0, 0.6)
    margin 16px 0
  .common-condition-con
    max-height 100px
    overflow-y scroll
    .add-btn
      color var(--mc-main-color)
      cursor pointer
      .MC_iconfont
        margin-right 4px
    :deep(.el-divider__text)
      color rgba(0, 0, 0, 0.6)
    .delet-span
      color rgba(0, 0, 0, 0.38)
      &:hover
        color #fc6c5c
    .common-contition-list
      display flex
      align-items center
      margin-bottom 10px
      gap 16px
    .order-num
      display inline-block
      width 14px
      color rgba(0, 0, 0, 0.6)
      margin-right -6px
.oprate
  padding 16px
  text-align right
  box-shadow 0px -1px 0px rgba(0, 0, 0, 0.05)
</style>
<style lang="stylus">
.advanced-search-pop
  padding 0 !important
</style>
